﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using SlimDX;
using SlimDX.Windows;
using SlimDX.DXGI;
using SlimDX.Direct3D11;
using Device = SlimDX.Direct3D11.Device;
using Resource = SlimDX.Direct3D11.Resource;
using System.Windows.Forms;
using SlimDX.D3DCompiler;

namespace LabyrinthGame
{
    public class Viewport2D : IDisposable
    {
        public Device device;
        public DeviceContext context;
        public Viewport viewport;
        public SwapChain swapChain;
        public RenderTargetView renderTarget;
        public SwapChainDescription description;

        public InputLayout inputLayout;

        private List<IDisposable> allResources = new List<IDisposable>(3);

        public Viewport2D(Form form, SwapChainDescription description)
        {
            this.description = description;
            Device.CreateWithSwapChain(
                DriverType.Hardware, 
                DeviceCreationFlags.None, 
                new FeatureLevel[] { FeatureLevel.Level_11_0 }, 
                description, 
                out device, 
                out swapChain);

            allResources.Add(device);
            allResources.Add(swapChain);

            //create a view of render target? which is the backbuffer of the swap chain
            using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
                renderTarget = new RenderTargetView(device, resource);

            viewport = new Viewport(0.0f, 0.0f, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f);
            context = device.ImmediateContext;

            context.OutputMerger.SetTargets(renderTarget);
            context.Rasterizer.SetViewports(viewport);

            allResources.Add(renderTarget);
            using (var factory = swapChain.GetParent<Factory>())
            {
                factory.SetWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAltEnter);
            }
        }

        public void Dispose()
        {
            foreach (IDisposable res in allResources)
            {
                res.Dispose();
            }
        }
    }
}
